﻿using Enterprises.Wpf.Core.Helper;
using System.Net.Sockets;
using System.Net;

namespace Enterprises.Wpf.Core.Entity
{
    /// <summary>
    /// 会话的基类信息
    /// </summary>
    public abstract class SessionBase
    {
        /// <summary>
        /// 实际传输数据的对象，除非你清楚自己在收发什么数据信息，否则尽量不直接使用本<see cref="T:System.Net.Sockets.Socket" />对象<br />
        /// The actual data transmission object, unless you know what data information you are sending and receiving, try not to directly use this <see cref="T:System.Net.Sockets.Socket" /> object
        /// </summary>
        public Socket WorkSocket { get; private set; }

        /// <summary>
        /// 获取当前的客户端的上线时间<br />
        /// Get the online time of the current client
        /// </summary>
        public DateTime OnlineTime { get; protected set; }

        /// <summary>
        /// 获取当前的远程连接对象的IP地址<br />
        /// Get the IP address of the current remote connection object
        /// </summary>
        public string IpAddress { get; protected set; }

        /// <summary>
        /// 获取当前的连接对象连接的远程客户端<br />
        /// Get the remote client connected by the current connection object
        /// </summary>
        public IPEndPoint IpEndPoint { get; protected set; }

        /// <summary>
        /// 获取心跳验证的时间点<br />
        /// Get the time point of heartbeat verification
        /// </summary>
        public DateTime HeartTime { get; private set; } = DateTime.Now;


        /// <summary>
        /// 实例化一个默认的对象
        /// </summary>
        public SessionBase()
        {
            OnlineTime = DateTime.Now;
        }

        /// <summary>
        /// 通过指定的<see cref="T:System.Net.Sockets.Socket" />对象来初始化一个会话内容
        /// </summary>
        /// <param name="socket">连接的Socket对象</param>
        public SessionBase(Socket socket)
            : this()
        {
            UpdateSocket(socket);
        }

        /// <summary>
        /// 更新当前的心跳时间<br />
        /// Update the current heartbeat time
        /// </summary>
        public void UpdateHeartTime()
        {
            HeartTime = DateTime.Now;
        }

        /// <summary>
        /// 更新当前的<see cref="T:System.Net.Sockets.Socket" />连接对象信息
        /// </summary>
        /// <param name="socket">连接的对象</param>
        public void UpdateSocket(Socket socket)
        {
            if (socket == null)
            {
                return;
            }
            WorkSocket = socket;
            try
            {
                IpEndPoint = WorkSocket.RemoteEndPoint as IPEndPoint;
                IpAddress = ((IpEndPoint == null) ? string.Empty : IpEndPoint.Address.ToString());
            }
            catch
            {
            }
        }
    }


    /// <summary>
    /// 当前的网络会话信息，还包含了一些客户端相关的基本的参数信息<br />
    /// The current network session information also contains some basic parameter information related to the client
    /// </summary>
    public class AppSession : SessionBase
    {
        /// <summary>
        /// UDP通信中的远程端<br />
        /// Remote side in UDP communication
        /// </summary>
        internal EndPoint UdpEndPoint = null;

        /// <summary>
        /// 远程对象的别名信息<br />
        /// Alias information for remote objects
        /// </summary>
        public string LoginAlias { get; set; }

        /// <summary>
        /// 客户端唯一的标识，在NetPushServer及客户端类里有使用<br />
        /// The unique identifier of the client, used in the NetPushServer and client classes
        /// </summary>
        public string ClientUniqueID { get; set; }

        /// <summary>
        /// 数据内容缓存<br />
        /// data content cache
        /// </summary>
        internal byte[] BytesBuffer { get; set; }

        /// <summary>
        /// 用于关键字分类使用<br />
        /// Used for keyword classification
        /// </summary>
        internal string KeyGroup { get; set; }

        /// <summary>
        /// 当前会话绑定的自定义的对象内容<br />
        /// The content of the custom object bound to the current session
        /// </summary>
        public object Tag { get; set; }

        /// <inheritdoc cref="M:HslCommunication.Core.Net.SessionBase.#ctor" />
        public AppSession()
        {
            ClientUniqueID = SoftBasic.GetUniqueStringByGuidAndRandom();
        }

        /// <inheritdoc cref="M:HslCommunication.Core.Net.SessionBase.#ctor(System.Net.Sockets.Socket)" />
        public AppSession(Socket socket)
            : base(socket)
        {
            ClientUniqueID = SoftBasic.GetUniqueStringByGuidAndRandom();
        }

        /// <inheritdoc />
        public override bool Equals(object obj)
        {
            return this == obj;
        }

        /// <inheritdoc />
        public override string ToString()
        {
            return string.IsNullOrEmpty(LoginAlias) ? $"AppSession[{base.IpEndPoint}]" : $"AppSession[{base.IpEndPoint}] [{LoginAlias}]";
        }

        /// <inheritdoc />
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

}
